home *** CD-ROM | disk | FTP | other *** search
/ Aminet 16 / Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso / Aminet / comm / term / term_source.lha / Extras / Source / term-source.lha / Hotkeys.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  7KB  |  396 lines

  1. /*
  2. **    Hotkeys.c
  3. **
  4. **    Hotkey support routines.
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. enum    {    CX_TERMSCREENTOFRONT,CX_BUFFERSCREENTOFRONT,CX_SKIPDIALENTRY,CX_ABORTAREXX };
  17.  
  18.     /* Asynchronous hotkey process. */
  19.  
  20. STATIC struct Process *CxProcess;
  21.  
  22. STATIC struct NewBroker TermBroker =
  23. {
  24.     NB_VERSION,
  25.     "term",
  26.     "term © 1990-1996 by Olaf Barthel",
  27.     "Terminal program"
  28. };
  29.  
  30.     /* Hotkey(STRPTR Code,struct MsgPort *Port,LONG ID):
  31.      *
  32.      *    A custom version of the amiga.lib supplied code.
  33.      */
  34.  
  35. STATIC CxObj *
  36. CustomHotKey(STRPTR Code,struct MsgPort *Port,LONG ID)
  37. {
  38.     CxObj *Filter;
  39.  
  40.     if(Filter = CxFilter(Code))
  41.     {
  42.         CxObj *Sender;
  43.  
  44.         if(Sender = CxSender(Port,ID))
  45.         {
  46.             CxObj *Translator;
  47.  
  48.             AttachCxObj(Filter,Sender);
  49.  
  50.             if(Translator = CxTranslate(NULL))
  51.             {
  52.                 AttachCxObj(Filter,Translator);
  53.  
  54.                 if(!CxObjError(Filter))
  55.                     return(Filter);
  56.             }
  57.         }
  58.  
  59.         DeleteCxObjAll(Filter);
  60.     }
  61.  
  62.     return(NULL);
  63. }
  64.  
  65.     /* CreateBroker(struct MsgPort *CxPort):
  66.      *
  67.      *    Set up a CxObj commodity broker.
  68.      */
  69.  
  70. STATIC CxObj *
  71. CreateBroker(struct MsgPort *CxPort)
  72. {
  73.     CxObj *Broker;
  74.  
  75.         /* Set the commodity priority. */
  76.  
  77.     TermBroker.nb_Pri = Hotkeys.CommodityPriority;
  78.  
  79.         /* Create the broker. */
  80.  
  81.     if(Broker = CxBroker(&TermBroker,NULL))
  82.     {
  83.             /* Add the hotkeys. */
  84.  
  85.         AttachCxObj(Broker,CustomHotKey(Hotkeys.termScreenToFront,        CxPort,CX_TERMSCREENTOFRONT));
  86.         AttachCxObj(Broker,CustomHotKey(Hotkeys.BufferScreenToFront,    CxPort,CX_BUFFERSCREENTOFRONT));
  87.         AttachCxObj(Broker,CustomHotKey(Hotkeys.SkipDialEntry,            CxPort,CX_SKIPDIALENTRY));
  88.         AttachCxObj(Broker,CustomHotKey(Hotkeys.AbortARexx,                CxPort,CX_ABORTAREXX));
  89.  
  90.             /* Did an error show up? */
  91.  
  92.         if(!CxObjError(Broker))
  93.         {
  94.                 /* Broker has been added, now activate it. */
  95.  
  96.             ActivateCxObj(Broker,Hotkeys.HotkeysEnabled);
  97.  
  98.             return(Broker);
  99.         }
  100.  
  101.         DeleteCxObjAll(Broker);
  102.     }
  103.  
  104.     return(NULL);
  105. }
  106.  
  107.     /* TermCxServer():
  108.      *
  109.      *    Asynchronous hotkey server.
  110.      */
  111.  
  112. STATIC VOID SAVE_DS
  113. TermCxServer(VOID)
  114. {
  115.     struct MsgPort *CxPort;
  116.     CxMsg *Message;
  117.     CxObj *Broker;
  118.  
  119.         /* Create a reply port. */
  120.  
  121.     if(CxPort = CreateMsgPort())
  122.     {
  123.             /* Add the port to the public list. */
  124.  
  125.         CxPort->mp_Node.ln_Name = TermBroker.nb_Name;
  126.  
  127.         AddPort(CxPort);
  128.  
  129.             /* Install the port. */
  130.  
  131.         TermBroker.nb_Port = CxPort;
  132.  
  133.             /* Create the broker. */
  134.  
  135.         if(Broker = CreateBroker(CxPort))
  136.         {
  137.             ULONG SignalSet;
  138.             BOOL Terminated;
  139.  
  140.                 /* Signal father task that we're done. */
  141.  
  142.             Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  143.  
  144.                 /* Loop and loop... */
  145.  
  146.             Terminated = FALSE;
  147.  
  148.             while(!Terminated)
  149.             {
  150.                     /* Wait for some signal. */
  151.  
  152.                 SignalSet = Wait(SIG_KILL | SIG_RESET | PORTMASK(CxPort));
  153.  
  154.                     /* ^C aborts. */
  155.  
  156.                 if(SignalSet & SIG_KILL)
  157.                     Terminated = TRUE;
  158.  
  159.                     /* ^D removes the broker and
  160.                      * creates a new one.
  161.                      */
  162.  
  163.                 if(SignalSet & SIG_RESET)
  164.                 {
  165.                     DeleteCxObjAll(Broker);
  166.  
  167.                     Broker = CreateBroker(CxPort);
  168.                 }
  169.  
  170.                     /* A commodity message. */
  171.  
  172.                 if(SignalSet & PORTMASK(CxPort))
  173.                 {
  174.                     ULONG MessageType,MessageID;
  175.  
  176.                         /* Remove all messages. */
  177.  
  178.                     while(Message = (CxMsg *)GetMsg(CxPort))
  179.                     {
  180.                             /* Extract type and ID. */
  181.  
  182.                         MessageType    = CxMsgID(Message);
  183.                         MessageID    = CxMsgType(Message);
  184.  
  185.                         ReplyMsg((struct Message *)Message);
  186.  
  187.                             /* Take a look at the type... */
  188.  
  189.                         switch(MessageID)
  190.                         {
  191.                                 /* A hotkey was pressed. */
  192.  
  193.                             case CXM_IEVENT:
  194.  
  195.                                 switch(MessageType)
  196.                                 {
  197.                                     case CX_TERMSCREENTOFRONT:
  198.  
  199.                                         Forbid();
  200.  
  201.                                         if(Window)
  202.                                             BumpWindow(TopWindow);
  203.                                         else
  204.                                             Signal((struct Task *)ThisProcess,SIGBREAKF_CTRL_F);
  205.  
  206.                                         Permit();
  207.  
  208.                                         break;
  209.  
  210.                                     case CX_BUFFERSCREENTOFRONT:
  211.  
  212.                                         LaunchBuffer();
  213.                                         break;
  214.  
  215.                                     case CX_SKIPDIALENTRY:
  216.  
  217.                                         Signal((struct Task *)ThisProcess,SIG_SKIP);
  218.                                         break;
  219.  
  220.                                     case CX_ABORTAREXX:
  221.  
  222.                                         if(InRexx)
  223.                                             Signal((struct Task *)ThisProcess,SIG_BREAK);
  224.  
  225.                                         break;
  226.                                 }
  227.  
  228.                                 break;
  229.  
  230.                                 /* An internal commodity command. */
  231.  
  232.                             case CXM_COMMAND:
  233.  
  234.                                 switch(MessageType)
  235.                                 {
  236.                                     case CXCMD_DISABLE:
  237.  
  238.                                         ActivateCxObj(Broker,Hotkeys.HotkeysEnabled = FALSE);
  239.                                         break;
  240.  
  241.                                     case CXCMD_ENABLE:
  242.  
  243.                                         ActivateCxObj(Broker,Hotkeys.HotkeysEnabled = TRUE);
  244.                                         break;
  245.                                 }
  246.  
  247.                                 break;
  248.                         }
  249.                     }
  250.                 }
  251.             }
  252.  
  253.                 /* Remove the broker. */
  254.  
  255.             DeleteCxObjAll(Broker);
  256.         }
  257.  
  258.             /* Remove the port from the public list. */
  259.  
  260.         RemPort(CxPort);
  261.  
  262.             /* Remove all pendig messages. */
  263.  
  264.         while(Message = (CxMsg *)GetMsg(CxPort))
  265.             ReplyMsg((struct Message *)Message);
  266.  
  267.             /* Delete the reply port. */
  268.  
  269.         DeleteMsgPort(CxPort);
  270.     }
  271.  
  272.     Forbid();
  273.  
  274.         /* Clear the task ID. */
  275.  
  276.     CxProcess = NULL;
  277.  
  278.         /* Signal father process that we're done. */
  279.  
  280.     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  281. }
  282.  
  283.     /* ShutdownCx():
  284.      *
  285.      *    Remove the hotkey task.
  286.      */
  287.  
  288. VOID
  289. ShutdownCx()
  290. {
  291.     ShakeHands((struct Task *)CxProcess,SIG_KILL);
  292. }
  293.  
  294.     /* SetupCx():
  295.      *
  296.      *    Create the hotkey task.
  297.      */
  298.  
  299. BOOL
  300. SetupCx()
  301. {
  302.         /* If the task is already running, tell it to
  303.          * update the hotkey settings.
  304.          */
  305.  
  306.     if(CxProcess)
  307.     {
  308.         Signal((struct Task *)CxProcess,SIG_RESET);
  309.  
  310.         return(TRUE);
  311.     }
  312.     else
  313.     {
  314.         if(CxProcess = StartProcessWaitForHandshake("term Hotkey Process",(TASKENTRY)TermCxServer,
  315.             NP_Priority,    0,
  316.             NP_WindowPtr,    -1,
  317.         TAG_DONE))
  318.             return(TRUE);
  319.     }
  320.  
  321.     return(FALSE);
  322. }
  323.  
  324.     /* LoadHotkeys(STRPTR Name,struct Hotkeys *Keys):
  325.      *
  326.      *    Load the hotkey settings from a file.
  327.      */
  328.  
  329. BOOL
  330. LoadHotkeys(STRPTR Name,struct Hotkeys *Keys)
  331. {
  332.     struct IFFHandle *Handle;
  333.     LONG Error;
  334.  
  335.     if(!(Handle = OpenIFFStream(Name,MODE_OLDFILE)))
  336.         Error = IoErr();
  337.     else
  338.     {
  339.         /* Collect version number ID if
  340.          * available.
  341.          */
  342.  
  343.         if(!(Error = PropChunks(Handle,(LONG *)VersionProps,1)))
  344.         {
  345.             /* The following line tells iffparse to stop at the
  346.              * very beginning of a `Type' chunk contained in a
  347.              * `TERM' FORM chunk.
  348.              */
  349.  
  350.             if(!(Error = StopChunk(Handle,ID_TERM,ID_HOTK)))
  351.             {
  352.                     /* Parse the file... */
  353.  
  354.                 if(!ParseIFF(Handle,IFFPARSE_SCAN))
  355.                 {
  356.                     struct StoredProperty *Prop;
  357.  
  358.                         /* Did we get a version ID? */
  359.  
  360.                     if(!(Prop = FindProp(Handle,ID_TERM,ID_VERS)))
  361.                         Error = ERROR_OBJECT_WRONG_TYPE;
  362.                     else
  363.                     {
  364.                         struct TermInfo *TermInfo;
  365.  
  366.                         TermInfo = (struct TermInfo *)Prop->sp_Data;
  367.  
  368.                         if((TermInfo->Version < CONFIG_FILE_VERSION) || (TermInfo->Version == CONFIG_FILE_VERSION && TermInfo->Revision < CONFIG_FILE_REVISION))
  369.                         {
  370.                             if(ReadChunkBytes(Handle,Keys,sizeof(struct HotkeysOld)) != sizeof(struct HotkeysOld))
  371.                                 Error = IoErr();
  372.                             else
  373.                                 strcpy(Keys->AbortARexx,"lshift rshift escape");
  374.                         }
  375.                         else
  376.                         {
  377.                             if(ReadChunkBytes(Handle,Keys,sizeof(struct Hotkeys)) != sizeof(struct Hotkeys))
  378.                                 Error = IoErr();
  379.                         }
  380.                     }
  381.                 }
  382.             }
  383.         }
  384.  
  385.         CloseIFFStream(Handle);
  386.     }
  387.  
  388.     if(Error)
  389.     {
  390.         SetIoErr(Error);
  391.         return(FALSE);
  392.     }
  393.     else
  394.         return(TRUE);
  395. }
  396.